Skip to main content

Visitor 패턴 및 java.nio.Path, PathMatcher, Files를 이용한 File찾기

· 4 min read
Ryukato
BackEnd Software Developer
ResourceMatcher class
import java.io.File;

public interface ResourceMatcher {
public static final String MATCH_PATTERN_PREFIX = "glob:";
boolean isMatch(File file);
}

AbstractResourceMatcher class
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;

public abstract class AbstractResourceMatcher implements ResourceMatcher {

@Override
public boolean isMatch(File file) {
String searchPattern = String.format("%s%s", ResourceMatcher.MATCH_PATTERN_PREFIX, getPattern());
Path path = file.toPath();
PathMatcher matcher = FileSystems.getDefault().getPathMatcher(searchPattern);
final boolean isMatch = matcher.matches(path.getFileName());
return isMatch;
}

abstract String getPattern();

}
ExcelFileMatcher class
public class ExcelFileMatcher extends AbstractResourceMatcher{
@Override
String getPattern() {
final String exelFilePattern = "*.{xlsx, xls}";
return exelFilePattern;
}

}
ImageFileMatcher class
public class ImageFileMatcher extends AbstractResourceMatcher{

@Override
String getPattern() {
final String imageFilePattern = "*.{jpg, png,bmp}";
return imageFilePattern;
}

}

JavaFileMatcher class
public class JavaFileMatcher extends AbstractResourceMatcher{

@Override
String getPattern() {
final String javaFilePattern = "*.{java, class}";
return javaFilePattern;
}

}

ResourceMatcherFactory class
public class ResourceMatcherFactory {
public enum ResourceType{
EXCEL, TEXT, IMAGE,JAVA;
}

private static ResourceMatcher excelFileMatcher = new ExcelFileMatcher();
private static ResourceMatcher textFileMatcher = new TextFileMatcher();
private static ResourceMatcher imageFileMatcher = new ImageFileMatcher();
private static ResourceMatcher javaFileMatcher = new JavaFileMatcher();

public static ResourceMatcher createMatcher(ResourceType resourceType){
if(resourceType == null){
final String exceptionMessage = "Empty(Null) resource type";
throw new RuntimeException(exceptionMessage);
}
ResourceMatcher testResourceMatch = null;
switch(resourceType){
case EXCEL:
testResourceMatch = excelFileMatcher;
break;
case TEXT:
testResourceMatch = textFileMatcher;
break;
case IMAGE:
testResourceMatch = imageFileMatcher;
break;
case JAVA:
testResourceMatch = javaFileMatcher;
break;
default:
testResourceMatch = textFileMatcher;
break;
}

return testResourceMatch;
}
}
ResourceFinder class
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;

import pattern.visitor.file2.matcher.ResourceMatcher;

public class ResourceFinder {
private static ResourceFinder INSTANCE = new ResourceFinder();

public static ResourceFinder getInstance(){
return ResourceFinder.INSTANCE;
}

public List<File> search(final File rootDirectory, final ResourceMatcher resourceMatcher){
Path path = Paths.get(rootDirectory.getPath());
return search(path, resourceMatcher);
}

public List<File> search(Path path, final ResourceMatcher resourceMatcher){
if(resourceMatcher == null){
throw new IllegalArgumentException("Empty ResourceMatcher");
}
final List<File> testCaseFileList = new ArrayList<File>();

try {
java.nio.file.Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file,BasicFileAttributes attrs) throws IOException {
File targetFile = file.toFile();
if(resourceMatcher.isMatch(targetFile)){
testCaseFileList.add(targetFile);
}
return FileVisitResult.CONTINUE;
}

});
}
catch (IOException e) {
String exceptionMessage = String.format("Resource searching failed - path:%s, exception: %s", path, e);
throw new RuntimeException(exceptionMessage, e);
}
return testCaseFileList;
}
}
ResourceFinderMain class
import java.io.File;
import java.util.List;

import pattern.visitor.file2.matcher.ResourceMatcher;
import pattern.visitor.file2.matcher.ResourceMatcherFactory;
import pattern.visitor.file2.matcher.ResourceMatcherFactory.ResourceType;

public class ResourceFinderMain {

public static void main(String[] args) {
ResourceFinder resourceFinder = ResourceFinder.getInstance();
File rootDirectory = new File("D:\\Test"); // 테스트 시 변경 필요
ResourceMatcher resourceMatcher = ResourceMatcherFactory.createMatcher(ResourceType.JAVA);
List<File> files = resourceFinder.search(rootDirectory, resourceMatcher);
printFileList(files);
}

private static void printFileList(List<File> files){
for(File file:files){
System.out.println(file);
}
}

}

java.nio.file.Files.walkFileTree 메서드를 통하여 주어진 root directory경로 아래의 모든 폴더 및 파일을 하나 하나 방문하면서 주어진 ResourceMatcher 객체가 반환 해주는 isMatch결과에 따라서 파일을 추가하는 구조입니다. ResourceMatcher의 구현체들은 ResourceMatcherFactory를 통하여 얻을 수 있습니다. 다만 ResourceMatcher의 구현체가 추가될때마다 ResourceMatcherFactory에 추가를 해줘야 하는 번거로움이 있을 수 있겠내요.

위의 구조를 바탕으로 Multi-Thread로 찾고자 하는 파일들을 찾는 다면 아주 짧은 시간안에 많은 파일을 찾을 수 있을 것 같내요.